import { _decorator, Component, Sprite, UITransform, Animation, AnimationClip, animation, SpriteFrame } from 'cc';
import { EntityManager } from '../../Base/EntityManager';
import { CONTROLLER_ENUM, DIRECTION_ENUM, DIRECTION_ORDER_ENUM, ENTITY_STATE_ENUM, ENTITY_TYPE_ENUM, EVENT_ENUM, PARAMS_NAME_ENUM } from '../../Enums';
import DataManager from '../../Runtime/DataManager';
import EventManager from '../../Runtime/EventManager';
import ResourceManager from '../../Runtime/ResourceManager';
import { TILE_HEIGHT, TILE_WIDTH } from '../Tile/TileManager';
import { PlayerStateMachine } from './PlayerStateMachine';
const { ccclass, property } = _decorator;

/**
 * 角色管理中心
 */
@ccclass('PlayerManager')
export class PlayerManager extends EntityManager {
  targetX:number = 0            // 角色移动方向（目标位置坐标）
  targetY:number = 0
  isMoving:boolean = false
  private readonly speed = 1/10 // 角色移动速度

  async init() {
    this.fsm = this.addComponent(PlayerStateMachine)
    // 这个 init 是异步的方法
    await this.fsm.init()
    // 为了确保 fsm 创建完成后再进行状态设置，对上面的 init 末尾进行了 await all 处理
    // this.fsm.setParams(PARAMS_NAME_ENUM.IDLE, true) 数据与ui分离
    super.init({
      x:2,
      y:8,
      direction:DIRECTION_ENUM.TOP,
      state:ENTITY_STATE_ENUM.IDLE,
      type:ENTITY_TYPE_ENUM.PLAYER
    })
    this.targetX = this.x
    this.targetY = this.y
    // 给事件中心绑定 移动操作为 move 方法
    EventManager.Instance.on(EVENT_ENUM.PLAYER_CTRL, this.inputHandle, this)

  }


  update() {
    this.updateXY()
    this.node.setPosition(this.x * TILE_WIDTH - TILE_WIDTH * 1.5, -this.y * TILE_HEIGHT +  TILE_HEIGHT * 1.5)
  }


  updateXY() {
    // 左右移动
    if (this.targetX < this.x) {
      this.x -= this.speed
    } else if (this.targetX > this.x) {
      this.x += this.speed
    }

    // 上下移动
    if (this.targetY < this.y) {
      this.y -= this.speed
    } else if (this.targetY > this.y) {
      this.y += this.speed
    }

    // 防止小数
    if (Math.abs(this.targetX - this.x) <= 0.1 && Math.abs(this.targetY - this.y) <= 0.1) {
      this.isMoving = false
      this.x = this.targetX
      this.y = this.targetY
      EventManager.Instance.emit(EVENT_ENUM.PLAYER_MOVE_END)
    }
  }
  inputHandle(inputDirection:CONTROLLER_ENUM) {
    if (this.willBlock(inputDirection)) {
      console.log('block')
      return
    }
    this.move(inputDirection)
  }

  // 角色移动 ->数据与ui分离：所有操作应当先改变数据，再改变视图
  move(inputDirection:CONTROLLER_ENUM) {
    if (inputDirection === CONTROLLER_ENUM.TOP) {
      this.isMoving = true
      this.targetY -= 1
    } else if (inputDirection === CONTROLLER_ENUM.BOTTOM) {
      this.isMoving = true
      this.targetY += 1
    } else if (inputDirection === CONTROLLER_ENUM.LEFT) {
      this.isMoving = true
      this.targetX -= 1
    } else if (inputDirection === CONTROLLER_ENUM.RIGHT) {
      this.isMoving = true
      this.targetX += 1
    } else if (inputDirection === CONTROLLER_ENUM.TURNLEFT) {
      // 向左转
      if (this.direction === DIRECTION_ENUM.TOP) {
        this.direction = DIRECTION_ENUM.LEFT
      } else if (this.direction === DIRECTION_ENUM.LEFT) {
        this.direction = DIRECTION_ENUM.BOTTOM
      } else if (this.direction === DIRECTION_ENUM.BOTTOM) {
        this.direction = DIRECTION_ENUM.RIGHT
      } else if (this.direction === DIRECTION_ENUM.RIGHT) {
        this.direction = DIRECTION_ENUM.TOP
      }
      EventManager.Instance.emit(EVENT_ENUM.PLAYER_MOVE_END)
      this.state = ENTITY_STATE_ENUM.TURNLEFT
    } else if (inputDirection === CONTROLLER_ENUM.TURNRIGHT) {
      // 向左转
      if (this.direction === DIRECTION_ENUM.TOP) {
        this.direction = DIRECTION_ENUM.RIGHT
      } else if (this.direction === DIRECTION_ENUM.LEFT) {
        this.direction = DIRECTION_ENUM.TOP
      } else if (this.direction === DIRECTION_ENUM.BOTTOM) {
        this.direction = DIRECTION_ENUM.LEFT
      } else if (this.direction === DIRECTION_ENUM.RIGHT) {
        this.direction = DIRECTION_ENUM.BOTTOM
      }
      EventManager.Instance.emit(EVENT_ENUM.PLAYER_MOVE_END)
      this.state = ENTITY_STATE_ENUM.TURNRIGHT
    }
  }

  willBlock(inputDirection:CONTROLLER_ENUM) {
    // 这里 x, y 就是角色当前的坐标
    const { targetX:x, targetY:y, direction } = this
    const { tileInfo } = DataManager.Instance
    const { mapRowCount: row, mapColumnCount: column } = DataManager.Instance;
    let moveFlag:boolean
    let turnleftFlag:boolean
    let turnrightFlag:boolean
    let playerNextX:number
    let weapenNextX:number
    let playerNextY:number
    let weapenNextY:number
    // 转角坐标（主角的旋转对角坐标）
    let turnX:number
    let turnY:number
    // 输入向上移动时
    if (inputDirection === CONTROLLER_ENUM.TOP) {
      moveFlag = true
      // 首先，角色不可以超出上边界
      playerNextX = x
      playerNextY = y - 1
      if (playerNextY < 0) {
        this.state = ENTITY_STATE_ENUM.BLOCKFRONT
        return true
      }
      // 接下来判断武器即将到达哪个位置，
      // 如果当前角色朝上
      if(direction === DIRECTION_ENUM.TOP) {
        weapenNextX = x
        weapenNextY = y - 2
      } // 朝下
      else if (direction === DIRECTION_ENUM.BOTTOM) {
        weapenNextX = x
        weapenNextY = y
      } // 朝左
      else if (direction === DIRECTION_ENUM.LEFT) {
        weapenNextX = x - 1
        weapenNextY = y - 1
      } // 朝右
      else if (direction === DIRECTION_ENUM.RIGHT) {
        weapenNextX = x + 1
        weapenNextY = y - 1
      }
    }

    // 输入向下移动时
    else if (inputDirection === CONTROLLER_ENUM.BOTTOM) {
      moveFlag = true
      // 首先，角色不可以超出下边界
      playerNextX = x
      playerNextY = y + 1
      if (playerNextY > column) {
        this.state = ENTITY_STATE_ENUM.BLOCKFRONT
        return true
      }
      // 接下来判断武器即将到达哪个位置，
      // 如果当前角色朝上
      if(direction === DIRECTION_ENUM.TOP) {
        weapenNextX = x
        weapenNextY = y
      } // 朝下
      else if (direction === DIRECTION_ENUM.BOTTOM) {
        weapenNextX = x
        weapenNextY = y + 2
      } // 朝左
      else if (direction === DIRECTION_ENUM.LEFT) {
        weapenNextX = x - 1
        weapenNextY = y + 1
      } // 朝右
      else if (direction === DIRECTION_ENUM.RIGHT) {
        weapenNextX = x + 1
        weapenNextY = y + 1
      }
    }

    // 输入向左移动时
    else if (inputDirection === CONTROLLER_ENUM.LEFT) {
      moveFlag = true
      // 首先，角色不可以超出左边界
      playerNextX = x - 1
      playerNextY = y
      if (playerNextX < 0) {
        this.state = ENTITY_STATE_ENUM.BLOCKFRONT
        return true
      }
      // 接下来判断武器即将到达哪个位置，
      // 如果当前角色朝上
      if(direction === DIRECTION_ENUM.TOP) {
        weapenNextX = x - 1
        weapenNextY = y - 1
      } // 朝下
      else if (direction === DIRECTION_ENUM.BOTTOM) {
        weapenNextX = x - 1
        weapenNextY = y + 1
      } // 朝左
      else if (direction === DIRECTION_ENUM.LEFT) {
        weapenNextX = x - 2
        weapenNextY = y
      } // 朝右
      else if (direction === DIRECTION_ENUM.RIGHT) {
        weapenNextX = x
        weapenNextY = y
      }
    }

    // 输入向右移动时
    else if (inputDirection === CONTROLLER_ENUM.RIGHT) {
      moveFlag = true
      // 首先，角色不可以超出右边界
      playerNextX = x + 1
      playerNextY = y
      if (playerNextX > row - 1) {
        this.state = ENTITY_STATE_ENUM.BLOCKFRONT
        return true
      }
      // 接下来判断武器即将到达哪个位置，
      // 如果当前角色朝上
      if(direction === DIRECTION_ENUM.TOP) {
        weapenNextX = x + 1
        weapenNextY = y - 1
      } // 朝下
      else if (direction === DIRECTION_ENUM.BOTTOM) {
        weapenNextX = x + 1
        weapenNextY = y + 1
      } // 朝左
      else if (direction === DIRECTION_ENUM.LEFT) {
        weapenNextX = x
        weapenNextY = y
      } // 朝右
      else if (direction === DIRECTION_ENUM.RIGHT) {
        weapenNextX = x + 2
        weapenNextY = y
      }
    }

    // 如果输入向左旋转时 ,需要判断 weapenNextX\Y的位置是否是turnable，用转角的turnX坐标判断
    else if (inputDirection === CONTROLLER_ENUM.TURNLEFT) {
      turnleftFlag = true
      // 确定转角
      if (direction === DIRECTION_ENUM.TOP) {
        turnX = x - 1
        turnY = y - 1
      } else if (direction === DIRECTION_ENUM.BOTTOM) {
        turnX = x + 1
        turnY = y + 1
      } else if (direction === DIRECTION_ENUM.LEFT) {
        turnX = x - 1
        turnY = y + 1
      } else if (direction === DIRECTION_ENUM.RIGHT) {
        turnX = x + 1
        turnY = y - 1
      }
    }
    // 如果输入向右旋转时 ,需要判断 weapenNextX\Y的位置是否是turnable，用转角的turnX坐标判断
    else if (inputDirection === CONTROLLER_ENUM.TURNRIGHT) {
      turnrightFlag = true
      // 确定转角
      if (direction === DIRECTION_ENUM.TOP) {
        turnX = x + 1
        turnY = y - 1
      } else if (direction === DIRECTION_ENUM.BOTTOM) {
        turnX = x - 1
        turnY = y + 1
      } else if (direction === DIRECTION_ENUM.LEFT) {
        turnX = x - 1
        turnY = y - 1
      } else if (direction === DIRECTION_ENUM.RIGHT) {
        turnX = x + 1
        turnY = y + 1
      }
    }

    if (moveFlag) {
      // 执行对武器碰撞判断
      const playerTile = tileInfo[playerNextX][playerNextY]
      const weapenTile = tileInfo[weapenNextX][weapenNextY]

      if(playerTile && playerTile.moveable && (!weapenTile || weapenTile.turnable)) {
      //empty
      } else {
        console.log(tileInfo)
        console.log('移动阻塞，因为:【playerTile】:', playerTile?'true':'false' ,)
        console.log('【playerTile.movable】:', playerTile.moveable ,'(',playerNextX,',', playerNextY,')')
        console.log('【weapenTile】:', weapenTile,)
        console.log('【weapenTile.turnable】:', weapenTile.turnable,)
        console.log('【(!x||y)】:', !weapenTile || weapenTile.turnable,)
        this.state = ENTITY_STATE_ENUM.BLOCKFRONT
        return true
      }
    } else if (turnleftFlag) {
      // 执行对转角碰撞判断
      if (
        (!tileInfo[x][turnY] || tileInfo[x][turnY].turnable) &&
        (!tileInfo[turnX][turnY] || tileInfo[turnX][turnY].turnable) &&
        (!tileInfo[turnX][y] || tileInfo[turnX][y].turnable)
      ) {
        // empty
      } else {
        this.state = ENTITY_STATE_ENUM.BLOCKTURNLEFT
        return true
      }
    } else if (turnrightFlag) {
      // 执行对转角碰撞判断
      if (
        (!tileInfo[x][turnY] || tileInfo[x][turnY].turnable) &&
        (!tileInfo[turnX][turnY] || tileInfo[turnX][turnY].turnable) &&
        (!tileInfo[turnX][y] || tileInfo[turnX][y].turnable)
      ) {
        // empty
      } else {
        this.state = ENTITY_STATE_ENUM.BLOCKTURNRIGHT
        return true
      }
    }

  }

}
